package cn.sciento.farm.devicemanager.gateway.schedule;

import cn.sciento.farm.devicemanager.common.constant.DeviceConstant;
import cn.sciento.farm.devicemanager.common.constant.MqttConstant;
import cn.sciento.farm.devicemanager.common.util.DateUtil;
import cn.sciento.farm.devicemanager.dao.entity.DevController;
import cn.sciento.farm.devicemanager.gateway.downlink.service.impl.MqttSendService;
import cn.sciento.farm.devicemanager.gateway.model.downlink.MqttContent;
import cn.sciento.farm.devicemanager.service.*;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @author wumu
 * @version V1.0
 * @date 6/15/18
 * @time 2:55 PM
 */
@Component
public class CheckOnline {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private CollectionService deviceCollectionService;

    @Autowired
    private ControllerService controllerService;

    @Autowired
    private MqttSendService mqttSendService;

    @Autowired
    private ControllerLogService controllerLogService;

    @Autowired
    private TimerLogService timerLogService;

    @Autowired
    private StrategyLogService strategyLogService;

    @Autowired
    private AlarmLogService alarmLogService;

    @Autowired
    private AlarmLogSendResultService alarmLogSendResultService;

    /**
     * 判断采集设备掉线
     */
    @Scheduled(cron = "0 0 0/1 * * ?")
    public void check() {
        int count = deviceCollectionService.updateOnlineByCheck(6);
        logger.info("总共有" + count + "个设备在检查中可能离线");
    }

    /**
     * 定时删除日志记录
     * cron = "0 0 0 1 1/3 ?" 每隔三个月的第一天执行一次
     */
    @Scheduled(cron = "0 0 0 1 1/3 ?")
    public void batchDeleteLog(){
        Date monthBefore = DateUtil.getTwoMonthBefore(new Date());
        long startTime = monthBefore.getTime();
        int controllerLogCount = controllerLogService.batchDeleteLogByStartTime(startTime);
        logger.info("已删除当前时间3个月前的"+ controllerLogCount+"条控制日志");
        int timerLogCount = timerLogService.batchDeleteLogByStartTime(startTime);
        logger.info("已删除当前时间3个月前的"+ timerLogCount+"条定时任务触发日志");
        int strategyLogCount = strategyLogService.batchDeleteLogByStartTime(startTime);
        logger.info("已删除当前时间3个月前的"+ strategyLogCount+"条策略触发日志");
        int alarmLogCount = alarmLogService.batchDeleteLogByCreateTime(startTime);
        logger.info("已删除当前时间3个月前的"+ alarmLogCount+"报警触发日志");
        int smsAlarmLogCount = alarmLogSendResultService.batchDeleteLogBysendTime(startTime);
        logger.info("已删除当前时间3个月前的"+ smsAlarmLogCount+"报警触发日志");
    }

    /**
     * 定时发送刷新指令
     * cron="0 0 1 * * ? " 每天凌晨1点执行
     */
    @Scheduled(cron="0 0 1 * * ? ")
    public void refreshDevice(){
        int totalCount = controllerService.getCount();
        System.out.println(totalCount);
        // 每页数据条数
        int pageSize = 1000;
        // 分页数量
        int totalPage = totalCount > pageSize ? totalCount/pageSize : 1;
        HashMap<String, Integer> map = new HashMap<>();
        map.put("refresh", 1);
        String payload = JSON.toJSONString(map);
        List<String> euiList = new ArrayList<>();
        for (int i = 1; i <= totalPage; i++) {
            List<DevController> list = controllerService.getListByLimit(i,pageSize);
            for (DevController devController : list) {
                String eui = devController.getEui();
                if (!euiList.contains(eui)){
                    euiList.add(eui);
                    String topic = String.format(MqttConstant.SCI_GW_CONFIG_TOPIC, eui);
                    mqttSendService.send(new MqttContent(topic,payload));
                }
            }
            euiList.clear();
            // 检查处理完毕
            if(list.size() < pageSize) {
                return;
            }
        }

    }

    /**
     * 判断控制设备是否在线,定时更新
     * cron="0 0 6 * * ? " 每天凌晨6点执行
     */
    @Scheduled(cron = "0 0 6 * * ?")
    public void changeOnlineByLastTime(){
        int totalCount = controllerService.getCount();
        // 每页数据条数
        int pageSize = 1000;
        // 分页数量
        int totalPage = totalCount > pageSize ? totalCount/pageSize : 1;
        long nowTime = System.currentTimeMillis();
        long fiveHoursAgo = 5 * 60 * 60 * 1000;
        for (int i = 1; i <= totalPage; i++) {
            List<DevController> list = controllerService.getListByLimit(i, pageSize);
            for (DevController devController : list) {
                long lastTime = devController.getLastTime();
                if(!devController.getProtocol().equals(DeviceConstant.SIMPLE)){
                    continue;
                }
                if (nowTime - lastTime < fiveHoursAgo) {
                    devController.setOnline(1);
                } else {
                    devController.setOnline(0);
//                    devController.setStatus(0);
                }
                controllerService.changeOnline(devController);
            }
        }
    }
}
